package cn.iocoder.yudao.module.product.evaluation.service;

import cn.iocoder.yudao.framework.business.evaluation.enums.ScoreTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.evaluation.dal.dataobject.ProductEvaluationDO;
import cn.iocoder.yudao.module.product.evaluation.vo.*;
import jakarta.annotation.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Map;
import java.util.Set;

/**
 * 产品评价 Service 实现类
 *
 * @author wangzhs
 */
@Service
@Validated
public interface ProductEvaluationService {

    /**
     * 创建产品评价
     * 后台管理员创建评论使用
     *
     * @param createReqVO 产品评价创建 Request VO 对象
     * @param virtual     是否虚拟
     */
    void createComment(ProductEvaluationCreateReqVO createReqVO, boolean virtual);

    /**
     * 创建评论
     * 创建产品评价 APP 端创建产品评价使用
     *
     * @param userId 用户编号
     * @param reqVO 创建请求
     * @return 返回评论 id
     */
    Long createComment(Long userId, AppProductEvaluationCreateReqVO reqVO);

    /**
     * 追加评论
     *
     * @param appendReqVO 创建请求 vo
     */
    void appendComment(AppProductEvaluationAppendReqVO appendReqVO);

    /**
     * 修改评论是否可见
     *
     * @param updateReqVO 修改评论可见
     */
    void updateCommentVisible(ProductEvaluationUpdateVisibleReqVO updateReqVO);

    /**
     * 回复评论
     *
     * @param replyVO     商家回复
     */
    void replyComment(ProductEvaluationReplyReqVO replyVO);

    /**
     * 回复评论
     *
     * @param replyVO 商家回复
     */
    void replyComment(AppProductEvaluationReplyReqVO replyVO);

    /**
     * 获得产品评价分页
     *
     * @param pageReqVO 分页查询
     * @return 产品评价分页
     */
    PageResult<ProductEvaluationDO> getCommentPage(ProductEvaluationPageReqVO pageReqVO);

    /**
     * 获得产品评价分页
     *
     * @param pageVO  分页查询
     * @param visible 是否可见
     * @return 产品评价分页
     */
    PageResult<ProductEvaluationDO> getCommentPage(AppProductEvaluationPageReqVO pageVO, Boolean visible);

    /**
     * 获得我的产品评价分页
     *
     * @param userId 用户编号
     * @param pageVO  分页查询
     * @return 产品评价分页
     */
    PageResult<ProductEvaluationDO> getMyCommentPage(Long userId, PageParam pageVO);

    /**
     * 根据产品SPU编号，计算产品评分
     *
     * @param spuId 产品SPU编号
     * @return 产品评分
     */
    float calculateScoreBySpuId(Long spuId);

    /**
     * 根据产品SPU编号，计算产品评分
     *
     * @param spuIds 产品SPU编号集合
     * @return 产品评分
     */
    Map<Long, Float> batchCalculateScoreBySpuIds(Set<Long> spuIds);

    /**
     * 根据店铺编号，计算店铺评分
     *
     * @param shopId 店铺编号
     * @return 店铺评分
     */
    float calculateScoreByShopId(Long shopId);

    /**
     * 根据店铺编号，计算店铺评分
     *
     * @param shopIds 店铺编号集合
     * @return 产品评分
     */
    Map<Long, Float> batchCalculateScoreByShopIds(Set<Long> shopIds);

    /**
     * 获得最新一条评论
     * @param spuId 产品SPU编号
     */
    ProductEvaluationDO getLatestCommentBySpuId(Long spuId);

    /**
     * 获得评价数量
     *
     * @param shopId      店铺编号
     * @param scoreType      评分类型
     * @param hasPictures      是否有图
     * @return 评价数量
     */
    Integer getCount(Long shopId, ScoreTypeEnum scoreType, @Nullable Boolean hasPictures);

    /**
     * 删除评论
     * @param userId 用户编号
     * @param id 编号
     */
    void deleteComment(Long userId, Long id);

    /**
     * 批量获得指定店铺的产品评价数
     *
     * @param shopIds 店铺编号列表
     * @return 产品评价数
     */
    Map<Long, Integer> getCommentCountByShopIds(Set<Long> shopIds);

}
